package ReentrantReadWriteLock_4;

import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.HashMap;
import java.util.Map;

class CacheSystem {
    private final Map<String, String> cache = new HashMap<>();
    private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();

    public String get(String key) {
        rwLock.readLock().lock();
        try {
            String value = cache.get(key);
            if (value != null) {
                System.out.println(Thread.currentThread().getName() + " 缓存命中: " + key);
                Thread.sleep(10); // 模拟读取缓存时间
                return value;
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            rwLock.readLock().unlock();
        }

        // 缓存未命中，升级为写锁
        rwLock.writeLock().lock();
        try {
            // 再次检查，防止其他线程已经写入
            String value = cache.get(key);
            if (value == null) {
                value = loadFromDB(key); // 模拟从数据库加载
                cache.put(key, value);
                System.out.println(Thread.currentThread().getName() + " 加载数据到缓存: " + key);
            }
            Thread.sleep(50); // 模拟数据库访问时间
            return value;
        } catch (InterruptedException e) {
            e.printStackTrace();
            return null;
        } finally {
            rwLock.writeLock().unlock();
        }
    }

    private String loadFromDB(String key) {
        return "数据_" + key;
    }
}

public class 读写锁升级_缓存系统 {
    public static void main(String[] args) {
        final CacheSystem cache = new CacheSystem();

        // 创建40个访问线程
        for (int i = 0; i < 40; i++) {
            final String key = "key-" + (i % 5); // 只有5个不同的key
            new Thread(new Runnable() {
                public void run() {
                    cache.get(key);
                }
            }, "访问线程-" + i).start();
        }
    }
}